/**
 * interaction.js
 * Copyright (C) 2007-2011 Tommi Rautava
 * 
 * This file is part of Popmungo.
 *
 * Popmungo is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Popmungo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * org.mozdev.popmungo.Interaction
 * 
 * 1 Greet
 * 2 Ask for autograph
 * 3 Talk to
 * 4 Tell joke
 * 5 Tease
 * 6 Google-Google
 * 7 Buy a drink
 * 8 Hug
 * 9 Kiss
 * 10 Kiss passionately
 * 11 Make Love
 * 12 Tickle
 * 13 5 minute quickie
 * 14 Compliment
 * 15 Insult
 * 16 Slap
 * 17
 * 18 Play with
 * 19
 * 20
 * 21 Sing to
 * 22
 * 23
 * 24 Wazzup call
 * 25 Lover call
 * 26 Prank call
 * 27 
 * 28 End relationship
 * 29 Seek apprenticeship
 * 30 
 * 31 Interrogate
 * 32 Give first aid
 * 33 Do funny magic
 * 34 Have profound discussion
 * 35 Ask for a dance
 * 46 Kiss my ass call
 */

org.mozdev.popmungo.classes.Interaction = function Interaction() {};

org.mozdev.popmungo.classes.Interaction.prototype = {
	
	DUMMY_OPTION_CLASS: 'popmungo_dummyOption',
	
	HIDE_OPTION_BUTTON_ID: 'popmungo_hideOption',
	
	UNHIDE_OPTION_BUTTON_ID: 'popmungo_unhideOption',
	
	SHOW_HIDDEN_OPTIONS_BUTTON_ID: 'popmungo_showOptions',
	
	HIDDEN_OPTION_CLASS: 'popmungo_hiddenOption',
	
	HIDDEN_OPTION_VISIBLE_CLASS: 'popmungo_hiddenOptionVisible',

	HIDDEN_OPTION_VISIBLE_HL_CLASS: 'popmungo_hiddenOptionVisibleHL',

	OPTION_ALERT_CLASS: 'popmungo_optionAlert',
	
	COMMAND_PREF_TEMPLATE: 'extensions.popmungo.options.interaction.option.<n>.command',
	
	HIGHLIGHT_PREF_TEMPLATE: 'extensions.popmungo.options.interaction.option.<n>.highlight.enabled',
	
	
	_getSelectInteractionElement: function _getSelectInteractionElement(doc) {
		try {
			return doc.getElementsByName('InteractionTypeID').item(0);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
		
		return null;
	},
	
	
	_addEmptyItem: function _addEmptyItem(doc, aSelectElem) {
		//org.mozdev.popmungo.logger.debug("aSelectElem="+ aSelectElem);

		/* No interaction:
		 * <select name="InteractionTypeID">
		 *     <option value="">------------</option>
		 * </select>
		 */
		
		var opt1 = doc.createElement('option');
		opt1.value = '';
		opt1.appendChild(doc.createTextNode('------------'));
		opt1.className = this.DUMMY_OPTION_CLASS;
		
		aSelectElem.appendChild(opt1);
	},
	
	
	_isClass: function _isClass(aNode, aClass) {
		if (aNode.className &&
			aNode.className.match(aClass))
		{
			return true;
		}
		
		return false;
	},
	
	
	_addClass: function _addClass(aNode, aClass) {
		if (aNode.className) {
			if (aNode.className.match(aClass)) {
				return; // Set already.
			}
			
			aNode.className = aNode.className +' '+ aClass;
			return;
		}

		aNode.className = aClass;
	},
	
	
	_replaceClass: function _replaceClass(aNode, aOldClass, aNewClass) {
		aNode.className = aNode.className.replace(aOldClass, aNewClass);
	},
	
	
	handleEvent: function handleEvent(e) {
		try {
			switch (e.currentTarget.id) {
			case this.SHOW_HIDDEN_OPTIONS_BUTTON_ID:
				return this.showHiddenInteractionOptionsButtonClicked(e);
				
			case this.HIDE_OPTION_BUTTON_ID:
				return this.hideInteractionOptionButtonClicked(e);

			default:
				org.mozdev.popmungo.logger.logError("Unexpected event: "+ e.type);
			}
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
		
		return true;
	},
	
	
	_selectFirstVisibleOption:
	function _selectFirstVisibleOption(selectInteraction) {
		try {
			var selectedIndex;
			var optionNode;
			
			// Find first visible option.
			for (selectedIndex = 0, optionNode; optionNode = selectInteraction[selectedIndex]; selectedIndex++) {
				
				if (this._isClass(optionNode, this.HIDDEN_OPTION_CLASS))
				{
					org.mozdev.popmungo.logger.debug(selectedIndex +': hidden');
					continue;
				}
	
				break; // TODO check this
			} 
			
			selectInteraction.selectedIndex = selectedIndex;
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
	},
	
	
	_hideHiddenOptions: function _hideHiddenOptions(doc, selectInteraction) {
		// Loop through all items.
		optionsLength = selectInteraction.length;

		for (var i = optionsLength - 1; i > -1; i--) {
			optionNode = selectInteraction.item(i);
			
			if (this._isClass(optionNode, this.HIDDEN_OPTION_VISIBLE_CLASS)) {
				this._replaceClass(optionNode, this.HIDDEN_OPTION_VISIBLE_CLASS, this.HIDDEN_OPTION_CLASS);
			}
			else if (this._isClass(optionNode, this.HIDDEN_OPTION_VISIBLE_HL_CLASS)) {
				this._replaceClass(optionNode, this.HIDDEN_OPTION_VISIBLE_HL_CLASS, this.HIDDEN_OPTION_CLASS);
			}	
		}

		this.addShowHiddenOptionsButton(doc);
		this._selectFirstVisibleOption(selectInteraction);
	},
	

	/**
	 * Move or remove certain interaction options to the end of the selection list.
	 * 
	 * @param doc
	 */
	sortInteractionChoises: function sortInteractionChoises(doc) {
		try {
			if (!org.mozdev.popmungo.prefs.isEnabled("extensions.popmungo.options.interaction.features.enabled")) {
				return;
			}
			
			var selectInteraction = this._getSelectInteractionElement(doc);
			
			if (!selectInteraction) {
				return;
			}
			
			// Loop through all items.
			optionsLength = selectInteraction.length;
	
			org.mozdev.popmungo.logger.debug("selectInteraction="+ selectInteraction + ", .length="+ selectInteraction.length);
	
			var hiddenOptions = 0;
			var n = 0;	
			var optionNode;
			
			for (var i = 0; i < optionsLength; i++) {
				optionNode = selectInteraction.item(n);
				
				if (!optionNode.value) {
					org.mozdev.popmungo.logger.debug('skipped item value='+ optionNode.value);
					continue;
				}
				
				var optionValue = parseInt(optionNode.value);
	
				var optionPrefName;
				var colorizePrefName;
	
				optionPrefName = this.COMMAND_PREF_TEMPLATE.replace(/<n>/, optionValue);
				colorizePrefName = this.HIGHLIGHT_PREF_TEMPLATE.replace(/<n>/, optionValue);
	
				var optionCommand = org.mozdev.popmungo.prefs.getPref(optionPrefName);
				var colorizeAction = org.mozdev.popmungo.prefs.getPref(colorizePrefName);
	
				org.mozdev.popmungo.logger.debug("optionValue="+ optionValue +
					", optionCommand="+ optionCommand +
					", colorizeAction="+ colorizeAction);
	
				if (colorizeAction) {
					this._addClass(optionNode, this.OPTION_ALERT_CLASS);
				}
	
				switch (optionCommand) {
					case 0: // Do nothing
						org.mozdev.popmungo.logger.debug("Keep option "+ optionValue);
						n++;
						break;

					case 1: // Move option to the end of the list
						org.mozdev.popmungo.logger.debug("Move option "+ optionValue);
						selectInteraction.remove(n);
						selectInteraction.appendChild(optionNode);
						break;
					
					case 2: // Hide option from the list
						org.mozdev.popmungo.logger.debug("Hide option "+ optionValue);
						this._addClass(optionNode, this.HIDDEN_OPTION_CLASS);
						hiddenOptions++;
						n++;
						break;
					
					case undefined:
						org.mozdev.popmungo.logger.debug("No command assigned");
						n++;
						break;
					
					default:
						org.mozdev.popmungo.logger.logError("Unknown command, code="+ optionCommand);
						n++;
				}			
			}
			
			// If the option list is empty, add a dummy item and disable the OK button.
			if ((selectInteraction.length - hiddenOptions) == 0) {
				org.mozdev.popmungo.logger.debug("Empty list, disable OK button");

				var okButton = selectInteraction.form.elements.namedItem("submit");
				okButton.disabled = true;

				this._addEmptyItem(doc, selectInteraction);
				selectInteraction.selectedIndex = selectInteraction.length - 1;
			}
			else {
				this._selectFirstVisibleOption(selectInteraction);
			}
			
			this.addHideOptionButton(doc);
			
			if (hiddenOptions > 0) {
				this.addShowHiddenOptionsButton(doc);	
			}
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
	},
	
	
	addShowHiddenOptionsButton:
	function addShowHiddenOptionsButton(doc) {
		try {
			var button1 = doc.getElementById(this.SHOW_HIDDEN_OPTIONS_BUTTON_ID);
			if (button1) {
				button1.disabled = false;
				return;
			}

			var selectInteraction = this._getSelectInteractionElement(doc);
			var text1 = org.mozdev.popmungo.strings.getString('interaction.showHiddenOptions', null);

			var button1 = doc.createElement('input');
			button1.type = "button";
			button1.id = this.SHOW_HIDDEN_OPTIONS_BUTTON_ID;
			button1.name = this.SHOW_HIDDEN_OPTIONS_BUTTON_ID;
			button1.value = text1;
			button1.addEventListener('click', this, true);

			var pn = selectInteraction.parentNode;
			pn.appendChild(doc.createElement('br'));
			pn.appendChild(button1);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
	},
	
	
	showHiddenInteractionOptionsButtonClicked:
	function showHiddenInteractionOptionsButtonClicked(aEvent) {
		try {
			var doc = aEvent.currentTarget.ownerDocument;
			var button1 = doc.getElementById(this.SHOW_HIDDEN_OPTIONS_BUTTON_ID);
			button1.disabled = true;

			var selectInteraction = this._getSelectInteractionElement(doc);
			
			if (!selectInteraction) {
				return true;
			}
			
			// Loop through all items.
			optionsLength = selectInteraction.length;
	
			org.mozdev.popmungo.logger.debug("selectInteraction="+ selectInteraction + ", .length="+ selectInteraction.length);
	
			for (var i = optionsLength - 1; i > -1; i--) {
				var optionNode = selectInteraction.item(i);
				
				if (this._isClass(optionNode, this.HIDDEN_OPTION_CLASS)) {
					var newClass = optionNode.style.backgroundColor ? 
						this.HIDDEN_OPTION_VISIBLE_HL_CLASS : 
						this.HIDDEN_OPTION_VISIBLE_CLASS;
					
					this._replaceClass(optionNode, this.HIDDEN_OPTION_CLASS, newClass);
				}
				else if (this._isClass(optionNode, this.DUMMY_OPTION_CLASS)) {
					optionNode.style.display = 'none';

					org.mozdev.popmungo.logger.debug(i +': dummy node is now hidden');
				}	
			}

			selectInteraction.selectedIndex = 0;
			
			var okButton = selectInteraction.form.elements.namedItem("submit");
			okButton.disabled = false;
			
			this.addUnhideOptionButton(doc);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
		
		return true;
	},
	
	
	addHideOptionButton:
	function addHideOptionButton(doc) {
		try {
			var selectInteraction = this._getSelectInteractionElement(doc);
			var text1 = org.mozdev.popmungo.strings.getString('interaction.hideOption', null);

			var button1 = doc.createElement('input');
			button1.type = "button";
			button1.id = this.HIDE_OPTION_BUTTON_ID;
			button1.name = this.HIDE_OPTION_BUTTON_ID;
			button1.value = text1;
			button1.addEventListener('click', this, true);

			var pn = selectInteraction.parentNode;
			pn.appendChild(doc.createElement('br'));
			pn.appendChild(button1);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
	},
			
			
	hideInteractionOptionButtonClicked:
	function hideInteractionOptionButtonClicked(aEvent) {
		try {
			var doc = aEvent.currentTarget.ownerDocument;
			//var button1 = doc.getElementById(this.HIDE_OPTION_BUTTON_ID);
			//button1.disabled = true;

			var selectInteraction = this._getSelectInteractionElement(doc);
			
			if (!selectInteraction) {
				return true;
			}
			
			var optionNode = selectInteraction.item(selectInteraction.selectedIndex);
			this._addClass(optionNode, this.HIDDEN_OPTION_CLASS);
			
			var optionValue = parseInt(optionNode.value);
			optionPrefName = this.COMMAND_PREF_TEMPLATE.replace(/<n>/, optionValue);
			org.mozdev.popmungo.prefs.setPref(optionPrefName, 2);

			this._hideHiddenOptions(doc, selectInteraction);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
		
		return true;
	},
	
	addUnhideOptionButton:
	function addUnhideOptionButton(doc) {
		try {
			var selectInteraction = this._getSelectInteractionElement(doc);
			var text1 = org.mozdev.popmungo.strings.getString('interaction.unhideOption', null);

			var button1 = doc.createElement('input');
			button1.type = "button";
			button1.id = this.UNHIDE_OPTION_BUTTON_ID;
			button1.name = this.UNHIDE_OPTION_BUTTON_ID;
			button1.value = text1;
			button1.addEventListener('click', this, true);

			var pn = selectInteraction.parentNode;
			pn.appendChild(doc.createElement('br'));
			pn.appendChild(button1);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
	},
	
	unhideInteractionOptionButtonClicked:
	function unhideInteractionOptionButtonClicked(aEvent) {
		try {
			var doc = aEvent.currentTarget.ownerDocument;

			var selectInteraction = this._getSelectInteractionElement(doc);
			
			if (!selectInteraction) {
				return true;
			}
			
			// Remove the class.
			var optionNode = selectInteraction.item(selectInteraction.selectedIndex);
			if (this._isClass(optionNode, this.HIDDEN_OPTION_VISIBLE_CLASS)) {
				this._replaceClass(optionNode, this.HIDDEN_OPTION_VISIBLE_CLASS, '');
			}
			else if (this._isClass(optionNode, this.HIDDEN_OPTION_VISIBLE_HL_CLASS)) {
				this._replaceClass(optionNode, this.HIDDEN_OPTION_VISIBLE_HL_CLASS, '');
			}	
			
			// Set the option.
			var optionValue = parseInt(optionNode.value);
			optionPrefName = this.COMMAND_PREF_TEMPLATE.replace(/<n>/, optionValue);
			org.mozdev.popmungo.prefs.setPref(optionPrefName, 0);
			
			// Hide rest of the options.
			this._hideHiddenOptions(doc, selectInteraction);
		}
		catch (err) {
			org.mozdev.popmungo.logger.logError(err);
		}
		
		return true;
	}
	
};

org.mozdev.popmungo.Interaction = new org.mozdev.popmungo.classes.Interaction();

// EOF